﻿using OA.Core.Helper;
using OA.Model.DB;
using OA.Web.Areas.Admin.Controllers;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;
using OA.Model;
using OA.Web.Controllers;
using OA.Web.Areas.Member.Controllers;
using Microsoft.Extensions.Primitives;

namespace OA.Web.Attribute
{
    public sealed class MyActionFilterAttribute : ActionFilterAttribute
    {
        public string Name
        {
            get; set;
        }

        public string Key { get; set; }

        /// <summary>
        /// 是否已选择
        /// </summary>
        public bool IsSelected { get; set; } = false;

        /// <summary>
        /// 是否是更新数据库操作
        /// </summary>
        public bool IsUpdateDataBase { get; set; } = false;

        public bool IsMenu { get; set; } = false;

        public string Url { get; set; }

        public string ParentName { get; set; }

        public string UserID { get; set; }

        public string Icon { get; set; }

        public string DataIconClass { get; set; }

        public MyActionFilterAttribute(string key, string name, string parentName="", bool isMenu=false, string icon = "", bool isUpdateDataBase = false)
        {
            this.Key = key;
            this.Name = name;
            this.ParentName = parentName;
            this.IsMenu = isMenu;
            this.IsUpdateDataBase = isUpdateDataBase;
            if(string.IsNullOrWhiteSpace(icon))
            {
                this.Icon = icon;
            }
        }


        public override void OnActionExecuting(ActionExecutingContext context)
        {
            bool flag = false;


            var controller = context.Controller as BaseMemberController;

            if (this.Key == "002")
            {
                string value = context.HttpContext.Request.Query[this.Name];
                int id = 0;
                if (Int32.TryParse(value, out id))
                {
                    int formGroupID = controller.dbContextFactory.DbContext.CustomForm.Where(m => m.ID == id).Select(m => m.FormGroupID).FirstOrDefault();
                    if (formGroupID > 0)
                    {
                        this.Key = this.Key + formGroupID.ToString("D3") + id.ToString("D3");
                    }
                }
            }
            else if (this.Key == "888")
            {
                string value=context.HttpContext.Request.Query[this.Name];
                int id = 0;
                if (Int32.TryParse(value, out id))
                {
                    this.Key = this.Key + id.ToString("D3");
                }
            }

            List<string> codes = controller.Codes;
            if (codes == null) codes = new List<string>();
            if (codes.Contains(this.Key))
            {
                flag = true;
            }
            controller.ViewBag.PermissionCode = codes;
            if (!flag)
            {
                var accessor = (IHttpContextAccessor)CallContext.GetData("IHttpContextAccessor");
                string url = string.Empty;
                if (accessor.HttpContext.Request.Method.ToLower() == "get")
                {
                    url = "/Member/Home/PermissionDenied?url=" + HttpUtility.UrlEncode(accessor.HttpContext.Request.GetEncodedUrl());
                }
                else
                {
                    url = "/Member/Home/PermissionDenied?url=" + HttpUtility.UrlEncode(accessor.HttpContext.Request.Headers["Referer"].ToString());
                }
                if (context.HttpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest")
                {
                    var result = new { State = 401, Msg = "" };
                    context.Result = new ContentResult() { Content = JsonConvert.SerializeObject(result) };
                }
                else
                {
                    context.Result = new RedirectResult(url);
                }
                return;
            }
            controller.ViewBag.PageCode = this.Key;
            base.OnActionExecuting(context);
        }

        /// <summary>
        /// 在action method调用后发生, 但是在result执行前发生 (在 view 呈现前)
        /// </summary>
        /// <param name="filterContext"></param>
        public override void OnResultExecuted(ResultExecutedContext context)
        {
            var accessor = (IHttpContextAccessor)CallContext.GetData("IHttpContextAccessor");
            var controller = context.Controller as BaseController;
            var isSuccess = true;
            if(controller.ViewBag.IsSucces !=null &&  !controller.ViewBag.IsSucces)
            {
                isSuccess = false;
            }

            if (this.IsUpdateDataBase && isSuccess)
            {
                string userName = string.Empty; ;
                if (context.Controller is BaseMemberController)
                {
                    Employee info = (Employee)CallContext.GetData("MemberInfo");
                    userName = info.EmpID;                    
                }
                OperationLogs operationLog = new OperationLogs();
                string data = string.Empty;
                if (accessor.HttpContext.Request != null && accessor.HttpContext.Request.Method=="Post"&&accessor.HttpContext.Request.Form != null) { data = accessor.HttpContext.Request.Form.ToJsonString(); }
                if (!string.IsNullOrWhiteSpace(data))
                {
                    data = Regex.Replace(data, "__RequestVerificationToken=[^&]+", "", RegexOptions.IgnoreCase | RegexOptions.Multiline);
                }
                if (!string.IsNullOrWhiteSpace(data))
                {
                    data = Regex.Replace(data, "pwd=[^&]+", "", RegexOptions.IgnoreCase | RegexOptions.Multiline);
                }
                string url = accessor.HttpContext.Request.GetDisplayUrl();
                url = Regex.Replace(url, "pwd=[^&]+", "", RegexOptions.IgnoreCase | RegexOptions.Multiline);
                operationLog.UserID = userName;

                if (string.IsNullOrWhiteSpace(data))
                {
                    data = controller.ViewBag.Data;
                }
                operationLog.Data = data;
                operationLog.IP = context.HttpContext?.Connection.RemoteIpAddress.ToString();
                operationLog.Method = accessor.HttpContext.Request.Method;
                operationLog.Url = url;
                operationLog.UserName = userName;
                operationLog.Name = this.Name;
                operationLog.CreateDateTime = DateTime.Now;
                operationLog.Key = this.Key;
                using (var dbContext = new MyDbContext())
                {
                    dbContext.OperationLogs.Add(operationLog);
                    dbContext.SaveChanges();
                }
            }
            base.OnResultExecuted(context);
        }

    }
}
